package com.eastcom.mystope.daemon.core.app;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.eastcom.mystope.common.util.SpringContextProvider;
import com.eastcom.mystope.daemon.config.BasePath;
import com.eastcom.mystope.daemon.context.ServerContext;
import com.eastcom.mystope.daemon.tools.TaskUtil;

public abstract class Application {

	private static Log logger = LogFactory.getLog(Application.class);

	protected ApplicationConfig config = null;

	private String[] springConfigFiles;

	protected String[] args;

	/**
	 * ��������������
	 * 
	 * @return
	 */
	abstract protected boolean preInitialize();

	/**
	 * ��ӡ������������
	 */
	abstract protected void printUsage();

	public Application() {

	}

	private void initContext() {
		SpringContextProvider springUtil = new SpringContextProvider();
		BasePath basePath = ServerContext.serverPath.getBaseConfigPath();
		List<String> pathList = new ArrayList<String>();
		pathList.add(basePath.getBase());
		if(basePath.getDao() != null)
			pathList.add(basePath.getDao());
		if(basePath.getJob() != null)
			pathList.add(basePath.getJob());
		if(basePath.getServer() != null)
			pathList.add(basePath.getServer());
		springConfigFiles = new String[pathList.size()];
		for(int i = 0; i < pathList.size(); i++){
			springConfigFiles[i] = pathList.get(i);
		}
		try {
			springUtil.setApplicationContext(new FileSystemXmlApplicationContext(springConfigFiles));
			setConfig((ApplicationConfig) springUtil.getBean("MainConfigBean"));

		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage(), e);
			logger.error("[E] Application config load error,exit ...");
			System.exit(1);
		}
	}

	/**
	 * ��������������
	 */
	abstract protected void mainloop();

	/**
	 * ����Ӧ�ó�������
	 * 
	 * @param args
	 */
	public void run() {
		if (args.length >= 1) {
			if (args[0].equalsIgnoreCase("start")) {
				if (!preInitialize()) 
				{
					logger.error("Initialize application error, exit...");
					System.exit(1);
				}
				initContext();
				mainloop();
				if (SpringContextProvider.getApplicationContext() != null)
					((AbstractApplicationContext) SpringContextProvider.getApplicationContext()).registerShutdownHook();
				logger.info(config.getAppName() + " graceful shutdown finished ");
				
			} else if (args[0].equalsIgnoreCase("stop")) {
				springConfigFiles = new String[1];
				springConfigFiles[0] = args[1];
				initContext();
				stop();
			} else if (args[0].equalsIgnoreCase("status")) {
				springConfigFiles = new String[1];
				springConfigFiles[0] = args[1];
				initContext();
				status(args);
			} else
				printUsage();
		} else{
			printUsage();
		}

	}

	/**
	 * ��ֹ����
	 */
	public void stop() {
	}

	/**
	 * �鿴����״̬
	 */
	public void status(String[] args) {
		StringBuffer sb = new StringBuffer();
		for(int i=0;i<args.length;i++){
			sb.append(args[i]).append(" ");
		}
	}

	/**
	 * ��ʾ����״̬
	 */
	abstract protected ArrayList displayStatus(String command);

	public void setConfig(ApplicationConfig config) {
		this.config = config;
	}

	public ApplicationConfig getConfig() {
		return config;
	}

	public static ApplicationContext getSpringCtx() {
		return SpringContextProvider.getApplicationContext();
	}

	public String[] getArgs() {
		return args;
	}

	public void setArgs(String[] args) {
		this.args = args;
	}
	
}